import { KNumTable, KStrTable } from '@coldcloude/kai2';
import { KKMapInfo, KKMapLayerInfo, KKMapTileInfo, KKP2D } from '@coldcloude/kakera';
import { _decorator, Component, JsonAsset, SpriteAtlas, SpriteFrame } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('MapResource')
export class MapResource extends Component {

    //config

    @property(JsonAsset)
    mapInfoJson:JsonAsset;

    @property(SpriteAtlas)
    tileAtlas:SpriteAtlas;

    @property(SpriteAtlas)
    objAtlas:SpriteAtlas;

    //runtime

    initialized = false;
    
    mapInfo:KKMapInfo;

    layerMap = new KStrTable<KKMapLayerInfo>();

    tileMap = new KNumTable<KKMapTileInfo>();

    objMap = new KNumTable<KKMapTileInfo>();

    _getLayerGrid(layerName:string,grid:KKP2D,op:(layer:KKMapLayerInfo,value:number)=>void){
        const layer = this.layerMap.get(layerName);
        if(layer){
            const index = grid.y*this.mapInfo.gridWidth+grid.x;
            const value = index>=0&&index<=layer.grids.length?layer.grids[index]:0;
            op(layer,value);
        }
    }

    getTag(layerName:string,grid:KKP2D):number{
        let tag = 0;
        this._getLayerGrid(layerName,grid,(layer:KKMapLayerInfo,value:number)=>{
            tag = value;
        });
        return tag;
    }

    getTileObject(layerName:string,grid:KKP2D):[KKMapTileInfo,SpriteFrame]{
        let rst:[KKMapTileInfo,SpriteFrame];
        this._getLayerGrid(layerName,grid,(layer:KKMapLayerInfo,value:number)=>{
            let map:KNumTable<KKMapTileInfo>;
            let atlas:SpriteAtlas;
            switch(layer.type){
                case "tile":
                    map = this.tileMap;
                    atlas = this.tileAtlas;
                    break;
                case 'object':
                    map = this.objMap;
                    atlas = this.objAtlas;
                    break;
            }
            if(map&&atlas){
                const info = map.get(value);
                if(info){
                    const sprite = atlas.getSpriteFrame(info.id);
                    rst = [info,sprite];
                }
            }
        });
        return rst;
    }

    init(){
        if(!this.initialized){
            this.initialized = true;
            this.mapInfo = this.mapInfoJson.json as KKMapInfo;
            for(const info of this.mapInfo.layers){
                this.layerMap.set(info.name,info);
            }
            for(const info of this.mapInfo.tiles){
                this.tileMap.set(info.mapId,info);
            }
            for(const info of this.mapInfo.objects){
                this.objMap.set(info.mapId,info);
            }
        }
    }
}
